#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
# Copyright (C) 2010 Vertical Communications
# Copyright (C) 2017 PTPT52
# Copyright (C) 2020 X-WRT <dev@x-wrt.com>

do_disk_ready() {
	which fdisk && which partx && which mkfs.ext4 || return
	local partdev
	local ROOTDEV=/dev/sda
	local ROOTPART=/dev/sda
	. /lib/upgrade/common.sh
	if export_bootdevice && export_partdevice partdev 0; then
		if echo $partdev | grep -q ^sd[a-z]; then
			ROOTDEV=/dev/${partdev}
			ROOTPART=/dev/${partdev}
		elif echo $partdev | grep -q ^mmcblk[0-9]; then
			ROOTDEV=/dev/${partdev}
			ROOTPART=/dev/${partdev}p
		else
			ROOTDEV=/dev/${partdev}
			ROOTPART=/dev/${partdev}
		fi
	fi

	test -b ${ROOTDEV} && test -b ${ROOTPART}1 || return

	overlay_size=$((1*1024*1024*1024)) #1G
	disktype="dos"
	fdisk -l ${ROOTDEV} 2>/dev/null | grep -q "type: gpt" && disktype="gpt"
	sector_size=`fdisk -l ${ROOTDEV} | grep "^Sector size" | awk '{print $4}'`
	sector_size=$((sector_size+0))
	test ${sector_size} -gt 0 || sector_size=512
	diskpart=`fdisk -l ${ROOTDEV} | grep "^${ROOTPART}[0-9]" | wc -l`
	O=0
	LASTDEV=`fdisk -l ${ROOTDEV} | grep "^${ROOTPART}[0-9]" | while read D _ E _; do
		if test $E -gt $O; then
			echo $D
			O=$E
		fi
	done | tail -n1`
	LASTNR=`echo $LASTDEV | grep -o "[0-9]*" | tail -n1`

	if [ "$disktype" = "gpt" ]; then
		which gdisk || return
		if [ "x$diskpart" = "x3" ] || [ "x$diskpart" = "x4" ]; then
			disksize="`fdisk -l ${ROOTDEV} | grep ${ROOTDEV}: | head -n1 | awk '{print $5}'`"
			test -n "$disksize" || return
			# <= 2GiB && return
			test $disksize -le 2147483648 && return

			#clean
			echo -ne "w\ny\ny\n" | gdisk ${ROOTDEV}
			echo -ne "d\n$((LASTNR+2))\nd\n$((LASTNR+1))\nw\ny\n" | gdisk ${ROOTDEV}
			set `fdisk -l ${ROOTDEV} 2>/dev/null | grep ^${ROOTPART}$((LASTNR))`
			sda4_start=$2
			sda4_end=$3

			# overlay partition
			sda5_start=$((sda4_end+512+1))
			sda5_end=$((sda5_start+overlay_size/sector_size - 1))

			# data partition
			sda6_start=$((sda5_end+512+1))

			# [_boot_|_rootfs_...1G...][cfg 1G][data...]
			echo -ne "n\n\n${sda5_start}\n${sda5_end}\n8300\nn\n\n${sda6_start}\n\n8300\nw\ny\n" | gdisk ${ROOTDEV}

			partx -a ${ROOTDEV}
			test -b ${ROOTPART}$((LASTNR+1)) -a -b ${ROOTPART}$((LASTNR+2))  || {
				MAJOR="`ls -l ${ROOTDEV} | grep ${ROOTDEV} | awk '{print $5}' | grep -o '[0-9]*'`"
				test -n "$MAJOR" && {
					rm -f ${ROOTPART}$((LASTNR+1))
					mknod ${ROOTPART}$((LASTNR+1)) b $MAJOR $((LASTNR+1))
					rm -f ${ROOTPART}$((LASTNR+2))
					mknod ${ROOTPART}$((LASTNR+2)) b $MAJOR $((LASTNR+2))
				}
			}

			# check to format
			if mount -t ext4 -o ro,noatime ${ROOTPART}$((LASTNR+2)) /mnt; then
				echo ${ROOTPART}$((LASTNR+2)) has valid filesystem, no need to format
				umount /mnt
			else
				test -b ${ROOTPART}$((LASTNR+2)) && echo erase >${ROOTPART}$((LASTNR+2))
			fi
			mount -o remount,rw / && {
				test -b ${ROOTPART}$((LASTNR+1)) && rm -f /etc/sda.ready
				mount -o remount,ro /
			}
			LASTNR=$((LASTNR+2))
		fi

		fstab=0
		if test -b ${ROOTPART}$((LASTNR-1)); then
			test -f /etc/sda.ready || {
				echo -ne 'y\n' | mkfs.ext4 ${ROOTPART}$((LASTNR-1))
				fstab=1
			}
			if mount -t ext4 -o ro,noatime ${ROOTPART}$((LASTNR-1)) /mnt; then
				umount /mnt
			else
				echo -ne 'y\n' | mkfs.ext4 ${ROOTPART}$((LASTNR-1))
				fstab=1
			fi
		fi
		[ "x$fstab" = "x1" ] && {
			mount -o remount,rw / && {
				cp /etc/fstab.config /tmp/fstab.config
				sed -i "s,/dev/sda3,${ROOTPART}$((LASTNR-1)),;s,/dev/sda4,${ROOTPART}$((LASTNR))," /tmp/fstab.config
				cp /tmp/fstab.config /etc/config/fstab
				mount -o remount,ro /
			}
		}
		test -b ${ROOTPART}$((LASTNR)) && [ "x`head -c5 ${ROOTPART}$((LASTNR))`" = "xerase" ] && {
			echo -ne 'y\n' | mkfs.ext4 ${ROOTPART}$((LASTNR))
		}
	elif [ "$disktype" = "dos" ]; then
		if [ "x$diskpart" = "x2" ]; then
			disksize="`fdisk -l ${ROOTDEV} | grep ${ROOTDEV}: | head -n1 | awk '{print $5}'`"
			test -n "$disksize" || return
			# <= 2GiB && return
			test $disksize -le 2147483648 && return

			#clean
			echo -ne "w\ny\ny\n" | fdisk ${ROOTDEV}
			echo -ne "d\n$((LASTNR+2))\nd\n$((LASTNR+1))\nw\ny\n" | fdisk ${ROOTDEV}
			set `fdisk -l ${ROOTDEV} 2>/dev/null | grep ^${ROOTPART}$((LASTNR))`
			sda2_start=$2
			sda2_end=$3

			# overlay partition
			sda3_start=$((sda2_end+512+1))
			sda3_end=$((sda3_start+overlay_size/sector_size - 1))

			# data partition
			sda4_start=$((sda3_end+512+1))

			# [_boot_|_rootfs_...1G...][cfg 1G][data...]
			echo -ne "n\np\n\n${sda3_start}\n${sda3_end}\nn\np\n${sda4_start}\n\nw\n" | fdisk ${ROOTDEV}

			partx -a ${ROOTDEV}
			test -b ${ROOTPART}$((LASTNR+1)) -a -b ${ROOTPART}$((LASTNR+2))  || {
				MAJOR="`ls -l ${ROOTDEV} | grep ${ROOTDEV} | awk '{print $5}' | grep -o '[0-9]*'`"
				test -n "$MAJOR" && {
					rm -f ${ROOTPART}$((LASTNR+1))
					mknod ${ROOTPART}$((LASTNR+1)) b $MAJOR $((LASTNR+1))
					rm -f ${ROOTPART}$((LASTNR+2))
					mknod ${ROOTPART}$((LASTNR+2)) b $MAJOR $((LASTNR+2))
				}
			}

			# check to format
			if mount -t ext4 -o ro,noatime ${ROOTPART}$((LASTNR+2)) /mnt; then
				echo ${ROOTPART}$((LASTNR+2)) has valid filesystem, no need to format
				umount /mnt
			else
				test -b ${ROOTPART}$((LASTNR+2)) && echo erase >${ROOTPART}$((LASTNR+2))
			fi
			mount -o remount,rw / && {
				test -b ${ROOTPART}$((LASTNR+1)) && rm -f /etc/sda.ready
				mount -o remount,ro /
			}
			LASTNR=$((LASTNR+2))
		fi

		fstab=0
		if test -b ${ROOTPART}$((LASTNR-1)); then
			test -f /etc/sda.ready || {
				echo -ne 'y\n' | mkfs.ext4 ${ROOTPART}$((LASTNR-1))
				fstab=1
			}
			if mount -t ext4 -o ro,noatime ${ROOTPART}$((LASTNR-1)) /mnt; then
				umount /mnt
			else
				echo -ne 'y\n' | mkfs.ext4 ${ROOTPART}$((LASTNR-1))
				fstab=1
			fi
		fi
		[ "x$fstab" = "x1" ] && {
			mount -o remount,rw / && {
				cp /etc/fstab.config /tmp/fstab.config
				sed -i "s,/dev/sda3,${ROOTPART}$((LASTNR-1)),;s,/dev/sda4,${ROOTPART}$((LASTNR))," /tmp/fstab.config
				cp /tmp/fstab.config /etc/config/fstab
				mount -o remount,ro /
			}
		}
		test -b ${ROOTPART}$((LASTNR)) && [ "x`head -c5 ${ROOTPART}$((LASTNR))`" = "xerase" ] && {
			echo -ne 'y\n' | mkfs.ext4 ${ROOTPART}$((LASTNR))
		}
	fi
}

boot_hook_add preinit_main do_disk_ready
